%scannertype LexicalParser
%scanbasetype LexicalScanner
%tokentype Token

%namespace Infinity.Parser.Lexical
%using Infinity.Parser.Syntax;

digits [0-9]+
character [a-zA-Z]+
whitespace [\r\t ]

%%

procedure				{ return (int)Token.PROCEDURE; }
operator				{ return (int)Token.OPERATOR; }

prefix  				{ return (int)Token.PREFIX; }
infix					{ return (int)Token.INFIX; }
postfix					{ return (int)Token.POSTFIX; }
iterative				{ return (int)Token.ITERATIVE; }

begin					{ return (int)Token.BEGIN; }
end						{ return (int)Token.END; }
return					{ return (int)Token.RETURN; }
if						{ return (int)Token.IF; }
then					{ return (int)Token.THEN; }
elseif					{ return (int)Token.ELSEIF; }
else					{ return (int)Token.ELSE; }
while					{ return (int)Token.WHILE; }
for						{ return (int)Token.FOR; }
foreach					{ return (int)Token.FOREACH; }
do 						{ return (int)Token.DO; }
in						{ return (int)Token.IN; }
out						{ return (int)Token.OUT; }
to						{ return (int)Token.TO; }
by						{ return (int)Token.BY; }
var						{ return (int)Token.VAR; }

:{whitespace}*=			{ return (int)Token.ASSIGNMENT; }
; 						{ return (int)Token.END_COMMAND; }

\(						{ return (int)Token.LEFT_REGULAR_PARENTHESES; }
\)						{ return (int)Token.RIGHT_REGULAR_PARENTHESES; }
\[						{ return (int)Token.LEFT_SQUARE_PARENTHESES; }
\]						{ return (int)Token.RIGHT_SQUARE_PARENTHESES; }
\{						{ return (int)Token.LEFT_CURLY_PARENTHESES; }
\}						{ return (int)Token.RIGHT_CURLY_PARENTHESES; }

\/\/.*					;

Q{whitespace}*:			{ return (int)Token.PRECONDITION; }
R{whitespace}*:			{ return (int)Token.POSTCONDITION; }

\,						{ return (int)Token.COMMA_SEPARATOR; }
:						{ return (int)Token.COLON; }

\-\>|@|&|#|$|%|!|?|\\|\.\.|\|\.	{ return (int)Token.OPERATOR_COMMAND; }
	
\+|\-|\*|\/|\^			{ return (int)Token.NUMERIC_OPERATOR; }

\<|\>|\<=|\>=|\=\=|\=|\<\>|\!=|\=\>|\<\=\>	{ return (int)Token.LOGICAL_OPERATOR; }


{digits}+				|
{digits}*\.{digits}+	|
{digits}+\.{digits}*	{ return (int)Token.NUMBER; }

\".+\"					{ return (int)Token.STRING; }

false|true				{ return (int)Token.BOOLEAN; }

({whitespace}|\n)+		;


({character}|_)({character}|{digits}|_)*	{ return (int)Token.IDENTIFIER; }

.						{
							Console.WriteLine("Unexpected character: {0}", yytext);
							return yylex();
						}
	
%%